// CharacterTracer.java
// Copyright (c) 2010 William Whitney
// All rights reserved.
// This software is released under the BSD license.
// Please see the accompanying LICENSE.txt for details.
package net.sourceforge.javaocr.ocrPlugins.charTracer;

import net.sourceforge.javaocr.ocr.ImageReader;
import net.sourceforge.javaocr.ocrPlugins.imgShearer.ImageShearer;
import net.sourceforge.javaocr.ocrPlugins.levelsCorrector.LevelsCorrector;
import net.sourceforge.javaocr.ocrPlugins.receiptFinder.ReceiptFinder;
import net.sourceforge.javaocr.scanner.DocumentScanner;
import net.sourceforge.javaocr.scanner.DocumentScannerListenerAdaptor;
import net.sourceforge.javaocr.scanner.PixelImage;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.IImageMetadata;
import org.apache.sanselan.common.ImageMetadata;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Saves all the characters in an image to an output directory individually.
 *
 * @author William Whitney
 */
public class CharacterTracer extends DocumentScannerListenerAdaptor {

    private DocumentScanner documentScanner = new DocumentScanner();
    private BufferedImage bfImage;
    private Graphics2D bfImageGraphics;

    public BufferedImage getTracedImage(File inputImage) {
        try {
            bfImage = ImageReader.read(inputImage);
            bfImageGraphics = bfImage.createGraphics();

            Image img = new BufferedImage(bfImage.getColorModel(), bfImage.getRaster(), bfImage.isAlphaPremultiplied(), null);
            PixelImage pixelImage = new PixelImage(img);
            pixelImage.toGrayScale(true);
            new LevelsCorrector().adjustImageLevels(pixelImage);
            pixelImage.filter();
            new ReceiptFinder().findReceipt(documentScanner, pixelImage);
            pixelImage = new ImageShearer().shearImage(documentScanner, pixelImage);

            BufferedImage newImage = new BufferedImage(pixelImage.width, pixelImage.height, BufferedImage.TYPE_BYTE_GRAY);
            WritableRaster raster = (WritableRaster) newImage.getData();

            raster.setPixels(0, 0, pixelImage.width, pixelImage.height, pixelImage.pixels);
            newImage.setData(raster);

            bfImage = newImage;
            bfImageGraphics = bfImage.createGraphics();

            documentScanner.scan(pixelImage, this, 0, 0, pixelImage.width, pixelImage.height);
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
        bfImageGraphics.dispose();

        return bfImage;
    }

    @Override
    public void processChar(PixelImage pixelImage, int x1, int y1, int x2, int y2, int rowY1, int rowY2) {
        try {
            bfImageGraphics.setStroke(new BasicStroke(4));
            bfImageGraphics.setColor(Color.red);
            bfImageGraphics.drawRect(x1, y1, x2 - x1, y2 - y1);
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void processSpace(PixelImage pixelImage, int x1, int y1, int x2, int y2) {
        try {
            bfImageGraphics.setStroke(new BasicStroke(4));
            bfImageGraphics.setColor(Color.yellow);
            bfImageGraphics.drawRect(x1, y1, x2 - x1, y2 - y1);
        } catch (Exception ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }

    private static final Logger LOG = Logger.getLogger(CharacterTracer.class.getName());
}
